package com.ruoyi.common.utils.http;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.FileEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * http请求工具类
 * <p>创建时间:2016年5月27日 下午4:30:02</p>
 * @author liuwp 
 * @version V1.0
 */
public class HttpRequest {
	/**
	 * 默认请求编码
	 */
	private String defaultContentEncoding;
	/**
	 * 请求连接超时时间
	 */
	private int connectTimeout;
	/**
	 * 读取超时时间
	 */
	private int readTimeout;
	/**
	 * http请求头
	 */
	private SortedMap<String, String> headerMap;
	
	public HttpRequest() {
		this.defaultContentEncoding = "utf-8";
		connectTimeout = 70000;
		readTimeout = 70000;
		headerMap = new TreeMap<String, String>();
	}
	
	/**
	 * 发送http get请求.
	 * @param url  请求地址
	 * @return HttpRespons
	 */
	public HttpRespons sendGet(String url){
		return sendGet(url, null, defaultContentEncoding);
	}
	
	/**
	 * 发送http get请求.
	 * @param url  请求地址
	 * @param map  请求参数
	 * @return HttpRespons
	 */
	public HttpRespons sendGet(String url, SortedMap<String, String> map){
		return sendGet(url, map, defaultContentEncoding);
	}
	
	/**
	 * 模拟表单请求.
	 * @param url 请求地址.
	 * @param map 参数设置.
	 * @return HttpRespons.
	 */
	public HttpRespons sendPost(String url, SortedMap<String, String> map){
		return sendPost(url, map, defaultContentEncoding);
	}
	
	/**
	 * 数据包请求.
	 * @param url 请求地址.
	 * @param data 请求数据包.
	 * @return HttpRespons.
	 */
	public HttpRespons sendPost(String url, String data){
		return sendPost(url, data, defaultContentEncoding);
	}
	
	/**
	 * 文件上传
	 * @param url 请求地址.
	 * @param file 文件对象.
	 * @return
	 */
	public HttpRespons sendPost(String url, File file){
		return sendPost(url, file, defaultContentEncoding);
	}
	
	/**
	 * 数据包请求.
	 * @param url 请求地址.
	 * @param data 请求数据包.
	 * @param charset 请求编码格式.
	 * @return HttpRespons.
	 */
	public HttpRespons sendPost(String url, String data, String charset) {
		long begTime = System.currentTimeMillis();
		HttpRespons httpRespons = new HttpRespons();
		HttpPost httpPost = null;
		try {
			HttpClient httpClient = HttpClients.createDefault();
			httpPost = new HttpPost(url);
			
			//设置超时时间
			RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(readTimeout).setConnectTimeout(connectTimeout).build();//设置请求和传输超时时间
			httpPost.setConfig(requestConfig);
			
			for(String key : headerMap.keySet()){
				httpPost.addHeader(key, headerMap.get(key));
			}
			
			StringEntity entity = new StringEntity(data, charset);
			httpPost.setEntity(entity);
			org.apache.http.HttpResponse response = httpClient.execute(httpPost);
			if (response != null) {
				HttpEntity resEntity = response.getEntity();
				if (resEntity != null) {
					httpRespons.setContent(EntityUtils.toString(resEntity, charset));
				}
				EntityUtils.consume(entity);
				
				httpRespons.setCode(response.getStatusLine().getStatusCode());
				httpRespons.setMessage(response.getStatusLine().getReasonPhrase());
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			httpRespons.setCode(309);
			httpRespons.setMessage(ex.getMessage());
		}finally {
			httpPost.releaseConnection();
			httpRespons.setUrl(url);
			httpRespons.setContentEncoding(charset);
			httpRespons.setConnectTimeout(connectTimeout);
			httpRespons.setReadTimeout(readTimeout);
			httpRespons.setRequestData(url + " post data:" + data);
			httpRespons.setRequestTime(System.currentTimeMillis() - begTime);
		}
		return httpRespons;
	}

	public HttpEntity sendPostStream(String url, String data) {
		HttpPost httpPost = null;
		try {
			HttpClient httpClient = HttpClients.createDefault();
			httpPost = new HttpPost(url);

			//设置超时时间
			RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(readTimeout).setConnectTimeout(connectTimeout).build();//设置请求和传输超时时间
			httpPost.setConfig(requestConfig);

			for(String key : headerMap.keySet()){
				httpPost.addHeader(key, headerMap.get(key));
			}

			StringEntity entity = new StringEntity(data, defaultContentEncoding);
			httpPost.setEntity(entity);
			org.apache.http.HttpResponse response = httpClient.execute(httpPost);
			return response.getEntity();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 文件上传
	 * @param url 请求地址.
	 * @param file 文件对象.
	 * @return
	 */
	public HttpRespons sendPost(String url, File file, String charset) {
		long begTime = System.currentTimeMillis();
		HttpRespons httpRespons = new HttpRespons();
		HttpPost httpPost = null;
		try {
			HttpClient httpClient = HttpClients.createDefault();
			httpPost = new HttpPost(url);
			
			//设置超时时间
			RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(readTimeout).setConnectTimeout(connectTimeout).build();//设置请求和传输超时时间
			httpPost.setConfig(requestConfig);
			
			for(String key : headerMap.keySet()){
				httpPost.addHeader(key, headerMap.get(key));
			}
			
			FileEntity entity = new FileEntity(file);
			httpPost.setEntity(entity);
			
			org.apache.http.HttpResponse response = httpClient.execute(httpPost);
			if (response != null) {
				HttpEntity resEntity = response.getEntity();
				if (resEntity != null) {
					httpRespons.setContent(EntityUtils.toString(resEntity, charset));
				}
				EntityUtils.consume(entity);
				
				httpRespons.setCode(response.getStatusLine().getStatusCode());
				httpRespons.setMessage(response.getStatusLine().getReasonPhrase());
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			httpRespons.setCode(309);
			httpRespons.setMessage(ex.getMessage());
		}finally {
			httpPost.releaseConnection();
			httpRespons.setUrl(url);
			httpRespons.setContentEncoding(charset);
			httpRespons.setConnectTimeout(connectTimeout);
			httpRespons.setReadTimeout(readTimeout);
			httpRespons.setRequestData(url + " post data:" + file);
			httpRespons.setRequestTime(System.currentTimeMillis() - begTime);
		}
		return httpRespons;
	}
	
	public HttpRespons wx_upload(String url, File file) {
		long begTime = System.currentTimeMillis();
		HttpRespons httpRespons = new HttpRespons();
		HttpPost httpPost = null;
		try {
			HttpClient httpClient = HttpClients.createDefault();
			httpPost = new HttpPost(url);
			
			//设置超时时间
			RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(readTimeout).setConnectTimeout(connectTimeout).build();//设置请求和传输超时时间
			httpPost.setConfig(requestConfig);
			
			for(String key : headerMap.keySet()){
				httpPost.addHeader(key, headerMap.get(key));
			}
			
			MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
    		multipartEntityBuilder
    		        .addBinaryBody("media", file)
    		        .setMode(HttpMultipartMode.RFC6532);
    		
    		httpPost.setHeader("Content-Type", ContentType.MULTIPART_FORM_DATA.toString());
    		HttpEntity entity = multipartEntityBuilder.build();
			httpPost.setEntity(entity);
			
			org.apache.http.HttpResponse response = httpClient.execute(httpPost);
			if (response != null) {
				HttpEntity resEntity = response.getEntity();
				if (resEntity != null) {
					httpRespons.setContent(EntityUtils.toString(resEntity));
				}
				EntityUtils.consume(entity);
				
				httpRespons.setCode(response.getStatusLine().getStatusCode());
				httpRespons.setMessage(response.getStatusLine().getReasonPhrase());
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			httpRespons.setCode(309);
			httpRespons.setMessage(ex.getMessage());
		}finally {
			httpPost.releaseConnection();
			httpRespons.setUrl(url);
			httpRespons.setConnectTimeout(connectTimeout);
			httpRespons.setReadTimeout(readTimeout);
			httpRespons.setRequestData(url + " post data:" + file);
			httpRespons.setRequestTime(System.currentTimeMillis() - begTime);
		}
		return httpRespons;
	}
	
	/**
	 * 模拟表单请求.
	 * @param url 请求地址.
	 * @param map 参数设置.
	 * @param charset 请求编码格式.
	 * @return HttpRespons.
	 */
	public HttpRespons sendPost(String url, SortedMap<String, String> map, String charset) {
		long begTime = System.currentTimeMillis();
		HttpRespons httpRespons = new HttpRespons();
		HttpPost httpPost = null;
		try {
			HttpClient httpClient = HttpClients.createDefault();
			httpPost = new HttpPost(url);
			
			//设置超时时间
			RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(readTimeout).setConnectTimeout(connectTimeout).build();//设置请求和传输超时时间
			httpPost.setConfig(requestConfig);
			
			for(String key : headerMap.keySet()){
				httpPost.addHeader(key, headerMap.get(key));
			}
			
			// 设置参数
			List<NameValuePair> list = new ArrayList<NameValuePair>();
			for (String key : map.keySet()) {
				list.add(new BasicNameValuePair(key, map.get(key)));
			}
			if (list.size() > 0) {
				UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, charset);
				httpPost.setEntity(entity);
			}
			org.apache.http.HttpResponse response = httpClient.execute(httpPost);
			if (response != null) {
				HttpEntity resEntity = response.getEntity();
				if (resEntity != null) {
					httpRespons.setContent(EntityUtils.toString(resEntity, charset));
				}
				EntityUtils.consume(resEntity);
				
				httpRespons.setCode(response.getStatusLine().getStatusCode());
				httpRespons.setMessage(response.getStatusLine().getReasonPhrase());
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			httpRespons.setCode(309);
			httpRespons.setMessage(ex.getMessage());
		}finally {
			httpPost.releaseConnection();
			httpRespons.setUrl(url);
			httpRespons.setContentEncoding(charset);
			httpRespons.setConnectTimeout(connectTimeout);
			httpRespons.setReadTimeout(readTimeout);
			httpRespons.setRequestData(url + " post params:" + mapToStr(map));
			httpRespons.setRequestTime(System.currentTimeMillis() - begTime);
		}
		return httpRespons;
	}
	/**
	 * 发送get请求.
	 * @param url 请求地址
	 * @param map 请求参数
	 * @param charset 字符集
	 * @return HttpRespons
	 */
	public HttpRespons sendGet(String url, SortedMap<String, String> map, String charset) {
		long begTime = System.currentTimeMillis();
		HttpRespons httpRespons = new HttpRespons();
		HttpGet httpGet = null;
		//设置请求参数
		String params = "";
		try {
			HttpClient client = HttpClients.createDefault();
			httpGet = new HttpGet();
			// 设置超时时间
			RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(readTimeout)
					.setConnectTimeout(connectTimeout).build();// 设置请求和传输超时时间
			httpGet.setConfig(requestConfig);

			for(String key : headerMap.keySet()){
				httpGet.addHeader(key, headerMap.get(key));
			}
			
			if(map != null){
				params = "?" + mapToStr(map);
			}
			httpGet.setURI(new URI(url + params));
			org.apache.http.HttpResponse response = client.execute(httpGet);
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				httpRespons.setContent(EntityUtils.toString(entity, charset));
			}
			EntityUtils.consume(entity);
			
			httpRespons.setCode(response.getStatusLine().getStatusCode());
			httpRespons.setMessage(response.getStatusLine().getReasonPhrase());
		} catch (Exception ex) {
			ex.printStackTrace();
			httpRespons.setCode(309);
			httpRespons.setMessage(ex.getMessage());
		}finally{
			httpGet.releaseConnection();
			httpRespons.setUrl(url);
			httpRespons.setContentEncoding(charset);
			httpRespons.setConnectTimeout(connectTimeout);
			httpRespons.setReadTimeout(readTimeout);
			httpRespons.setRequestData(url + params);
			httpRespons.setRequestTime(System.currentTimeMillis() - begTime);
		}
		return httpRespons;
	}
	
	private String mapToStr(SortedMap<String, String> __l){
    	StringBuffer sb = new StringBuffer();
    	if(__l!=null && __l.size()>0){
    		for (String k : __l.keySet()) {
    			if(sb.length()==0){
    				sb.append(k).append("=").append(__l.get(k));
    			}else{
    				sb.append("&").append(k).append("=").append(__l.get(k));
    			}
    		}
    	}
    	return sb.toString();
    }
	
	/**
	 * @param defaultContentEncoding 设置默认的响应字符集
	 */
	public void setDefaultContentEncoding(String defaultContentEncoding) {
		this.defaultContentEncoding = defaultContentEncoding;
	}

	/**
	 * @param connectTimeout 设置连接时间
	 */
	public void setConnectTimeout(int connectTimeout) {
		this.connectTimeout = connectTimeout;
	}

	/**
	 * @param readTimeout 设置读取时间
	 */
	public void setReadTimeout(int readTimeout) {
		this.readTimeout = readTimeout;
	}
	/**
	 * 设置请求头
	 * @param key
	 * @param value 
	 */
	public void addHeader(String key, String value){
		this.headerMap.put(key, value);
	}

}
